package districting;

import java.util.Comparator;

import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;

public class PollingBoothCompactnessComparatorB implements
      Comparator<PollingBooth> {

   private double compact(Geometry geom) {
      return geom.getArea() / Math.pow(geom.getLength(), 2);
   }

   Division division;

   DivisionMethod method;

   public PollingBoothCompactnessComparatorB(Division division,
         DivisionMethod method) {
      this.division = division;
      this.method = method;
   }

   @Override
   public int compare(PollingBooth pb0, PollingBooth pb1) {
      Geometry geom = new GeometryFactory().createGeometry(division
            .getPolygon());
      Geometry newGeom0 = geom.union(pb0.getPolygon());
      Geometry newGeom1 = geom.union(pb1.getPolygon());
      Geometry other0 = new GeometryFactory().createGeometry(pb0.getDivision(
            method).getPolygon());
      Geometry other1 = new GeometryFactory().createGeometry(pb1.getDivision(
            method).getPolygon());
      Geometry newOther0 = other0.difference(pb0.getPolygon());
      Geometry newOther1 = other1.difference(pb1.getPolygon());

      if (newGeom0.getNumGeometries() < geom.getNumGeometries()
            || newOther0.getNumGeometries() < other0.getNumGeometries()) {
         return -1;
      } else if (newGeom1.getNumGeometries() < geom.getNumGeometries()
            || newOther1.getNumGeometries() < other1.getNumGeometries()) {
         return 1;
      }

      double compact0 = (compact(geom) + compact(other0))
            / (compact(newGeom0) + compact(newOther0));
      double compact1 = (compact(geom) + compact(other1))
            / (compact(newGeom1) + compact(newOther1));
      if (compact0 < compact1) {
         return -1;
      } else if (compact0 > compact1) {
         return 1;
      } else {
         return 0;
      }
   }

}
